#include "memory.h"
#include"Options.h"
#include "strategy.h"

CMemory::CMemory()
{
	strategy_ = 0;
}

void CMemory::Create()
{	
	strategy_ = new CLimitedCacheMemory(theOptions->max_msg_cache_size,theOptions->max_block_cache_size,theOptions->max_message_size);
}

CMemory::~CMemory()
{
	block* pBlock = block_pool.get();
	while(pBlock)
	{
			strategy_->force_free_block(pBlock);
			pBlock = block_pool.get();
	}	
	
	msg* pMsg = msg_pool.get();
	while(pMsg)
	{
		strategy_->force_free_msg(pMsg);
		pMsg = msg_pool.get();
	}

	if(0!=strategy_)
	{
		delete strategy_;
		strategy_ = 0; 
	}
}

struct block* CMemory::alloc_block()
{
	block* ret = 0;
	ret = block_pool.get();
	if(0==ret)
		ret = strategy_->alloc_block();

	ret->next = 0;
	ret->refcount = 1;

	return ret;
}

void 
CMemory::free_block(struct block* ptr_block)
{
	if(ptr_block&&ptr_block->release())
	{
		strategy_->free_block(ptr_block);
		if(0!=ptr_block)
			block_pool.add_head(ptr_block);	
	}
}

struct msg* CMemory::alloc_msg()
{
	msg* ret = 0;
	ret = msg_pool.get();
	if(0==ret)
		ret = strategy_->alloc_msg();

	ret->next = 0;
	ret->readpos = 0;
	ret->writepos = 0;
	ret->data = 0;
	ret->totalsize = 0;	
	return ret;
}

void CMemory::free_msg(struct msg* ptr_msg)
{
	if(!ptr_msg) return;

	if(ptr_msg->data)
		free_block(ptr_msg->data);
	ptr_msg->data = 0;

	strategy_->free_msg(ptr_msg);
	if(ptr_msg)
		msg_pool.add_head(ptr_msg);
}
